P2895 (USACO08FEB) Meteor Shower S
题目描述
贝茜听说一场特别的流星雨即将到来:这些流星会撞向地球,并摧毁它们所撞击的任何东西。她为自己的安全感到焦虑,发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。
如果将牧场放入一个直角坐标系中,贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。
根据预报,一共有
贝茜在时刻
请你计算一下,贝茜最少需要多少时间才能到达一个安全的格子。如果不可能到达输出
输入格式
共
输出格式
贝茜到达安全地点所需的最短时间,如果不可能,则为
样例 1
样例输入
4
0 0 2
2 1 2
1 1 2
0 3 5
样例输出
5
代码
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int m;
int ans[305][305], death[305][305];//记录答案和死亡时间
struct coord {int x, y;};
queue<coord> Q; //记录状态
const int walk[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void update(int a, int b, int t) {
if (a >= 0 && a < 305 && b >= 0 && b < 305) // 边界检查
death[a][b] = min(death[a][b], t);
}
int main() {
//数据初始化并记录地块最早失效时间
cin >> m;
memset(death, 0x3f, sizeof(death));
memset(ans, -1, sizeof(ans));
for (int i = 0; i < m; i++) {
int x, y, t;
scanf("%d%d%d", &x, &y, &t);
update(x, y, t);
for (int i = 0; i < 4; i++) {
int p = x + walk[i][0];
int q = y + walk[i][1];
update(p, q, t);}
}
//队列初始化
Q.push((coord){0, 0});
ans[0][0] = 0;
while (!Q.empty()) {
coord u = Q.front();
int ux = u.x, uy = u.y;
if (death[ux][uy] > 1000) {
cout << ans[ux][uy];
return 0;
} //如果安全就结束
Q.pop();
for (int i = 0; i < 4; i++) {
int x = ux + walk[i][0], y = uy + walk[i][1];
if (0 <= x && x < 305 && 0 <= y && y < 305 && ans[x][y] == -1 && ans[ux][uy] + 1 < death[x][y]) {
ans[x][y] = ans[ux][uy] + 1;
Q.push((coord){x, y});
}
}
}
cout << -1;
}
思路
广度优先搜索,注意边界条件